<?php
/**
 * 发布/订阅模式-发布者
 * Created by PhpStorm.
 * User: august
 * Date: 2021/4/10
 * Time: 13:06
 */

namespace Aug\Tools\Design;


use SplObserver;
use SplSubject;

class Publisher implements SplSubject
{
    protected $name;
    protected $data;
    protected $linked;
    protected $subscribers;

    public function __construct($name)
    {
        $this->name = $name;
        $this->data = [];
        $this->subscribers = [];
        $this->linked = [];
    }

    public function __toString()
    {
        return $this->name;
    }

    public function attach(SplObserver $subscriber)
    {
        $this->subscribers[$subscriber->getKey()] = $subscriber;
        $this->linked[$subscriber->getKey()] = $subscriber->getPriority();
        // 降序排列 r:reverse a:association
        arsort($this->linked);
    }

    public function detach(SplObserver $subscriber)
    {
        unset($this->subscribers[$subscriber->getKey()]);
        unset($this->linked[$subscriber->getKey()]);
    }

    public function notify()
    {
        foreach ($this->linked as $key => $priority) {
            $this->subscribers[$key]->update($this);
        }
    }

    public function getName()
    {
        return $this->name;
    }

    public function setName($name)
    {
        $this->name = $name;
    }

    public function setData(array $data)
    {
        $this->data = $data;
    }

    public function getData()
    {
        return $this->data;
    }

    public function setDataByKey($key, $value)
    {
        $this->data[$key] = $value;
    }

    public function getDataByKey($key, $default = null)
    {
        return isset($this->data[$key]) ? $this->data[$key] : $default;
    }
}